
#include <stdio.h>
#include <string.h>
#include "lora.h"
#include "bspSysTick.h"
#include "bspUsart.h"
#include "rs485.h"
#include "bspLed.h"

char Lora_TxData[256];
u32 Valid_Data_Len_Max=101;

const char* sBase_AT = {"AT"};
const char* sBase_RESET = {"RESET"};
const char* sBase_SAVE = {"SAVE"};
const char* sBase_VERS = {"VERS"};
const char* sBase_BAUD = {"BAUD"};
const char* sBase_CONFIRM = {"CONFIRM"};
const char* sBase_NBTRIALS = {"NBTRIALS"};
const char* sBase_ADR = {"ADR"};
const char* sBase_CLASS = {"CLASS"};
const char* sBase_PORT = {"PORT"};
const char* sBase_LINK = {"LINK"};
const char* sBase_SIGNAL = {"SIGNAL"};
const char* sBase_DATARATE = {"DATARATE"};
const char* sBase_SEND = {"SEND"};
const char* sBase_SENDCK = {"SENDCK"};
const char* sBase_JOIN = {"JOIN"};
const char* sBase_SLEEP = {"SLEEP"};
const char* sBase_HEART = {"HEART"};
const char* sBase_CHANNEL = {"CHANNEL"};
const char* sBase_DEVEUI = {"DEVEUI"};
const char* sBase_APPEUI = {"APPEUI"};
const char* sBase_APPKEY = {"APPKEY"};
const char* sBase_POWER = {"POWER"};
const char* sBase_AUTO = {"AUTO"};

void LoRaJoinNet();

char gLoraSetBuffer[50];
char * gptrLoraRx = NULL;
int	 gLoraRxSize = 0;
u32  gLoRaRxFlag = 0;
u32  Rs485RxFlag = 0;

void Usart3RxCallback(void)
{
	if(!gLoRaRxFlag) gLoRaRxFlag = 1;
}

void Usart2RxCallback(void)
{
	if(!Rs485RxFlag) Rs485RxFlag = 1;
}

static void LoRaSetALoW(void)
{
	GPIO_ResetBits(GPIOB, GPIO_Pin_9);
}

static void LoRaSetAHigh(void)
{
	GPIO_SetBits(GPIOB, GPIO_Pin_9);
}

static void LoRaCtrlIOInit(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; 
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7; 
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	LoRaSetAHigh();
}

void LoRaInit(void)
{
	int initState;
	u32 timeout;
	u32 lora_net_fail_time;
	u16 i;
	
	initState = 1;
	timeout = 0;
	lora_net_fail_time = 0;
	
	while(initState)
	{		

		switch(initState)
		{
			case 1:
					LoRaCtrlIOInit();
					bspUsart3Init(9600);
					initState = 2;
					delay(100);
				break;
			case 2:
					bspUsart3CleanData();
					LoRaSetALoW(); 
					delay(5);
					LoRaSetAHigh();
					i=60;
					while(i--)
					{
						if(gLoRaRxFlag)
						{
							gLoRaRxFlag = 0;
							gLoraRxSize = bspUsart3Receive((void*)&gptrLoraRx);
							if(strstr(gptrLoraRx, "OK+SLEEP:00\r\n") != NULL)
							{
								
								initState = 4;
								break;
							}
							else
							{
								
							}
						}
						delay(200);
					}
					
					initState = 4;
					break;

			case 4:
					bspUsart3CleanData();
					
					bspUsart3Send("AT+SLEEP=00\r\n",13);
					i=10;
					while(i--)
					{
						if(gLoRaRxFlag)
						{
							gLoRaRxFlag = 0;
							gLoraRxSize = bspUsart3Receive((void*)&gptrLoraRx);
							if(strstr(gptrLoraRx, "OK+SLEEP:00\r\n") != NULL)
							{
								initState = 5;
								break;
							}
							else
							{
							}
						}
						delay(200);
						if(1==i)
						{
							initState = 2; 
							break;
						}
					}
					break;
			case 5:
				bspUsart3CleanData();
				LoRaGetCmd(LORA_GET_JOIN);
				delay(1000);
				i=100;
				while(i--)
				{
					if(gLoRaRxFlag)
						{
							gLoRaRxFlag = 0;						
							gLoraRxSize = bspUsart3Receive((void*)&gptrLoraRx);
							if(strstr(gptrLoraRx, "OK+JOIN:00\r\n") != NULL)
							{
								
								bspUsart3Send("AT+JOIN=1\r\n",11);
								delay(1000);
								bspUsart3CleanData();
								
							}
							else if(strstr(gptrLoraRx, "OK+JOIN:01\r\n") != NULL)
							{
								delay(1000);
							}
							else if(strstr(gptrLoraRx, "OK+JOIN:02\r\n") != NULL)
							{
								
								initState = 0;
								bspUsart3CleanData();
								return ;
							}
							else if(strstr(gptrLoraRx, "ERR+JOINED:0005,0005\r\n") != NULL)
							{
								initState = 0;
								bspUsart3CleanData();
								return;
							}
							
							
							break;
						}
						
				}
				
				break;				
				
		}
		
		
		bspLedToggle(LED0);
		bspUsart3CleanData();
	}

}


void LoRaRunCmd(LoRaRunATCmd type)
{
	u32 size = 0;
	const	char* pAT = sBase_AT;
	const	char* pName = NULL;
	
	switch(type)
	{
		case LORA_RUN_TEST:
				pName = NULL;
			break;
		case LORA_RUN_RESET:
				pName = sBase_RESET;
			break;
		case LORA_RUN_SAVE:
				pName = sBase_SAVE;
			break;
		case LORA_RUN_HEART:
				pName = sBase_HEART;
			break;
		case LORA_RUN_LINK:
				pName = sBase_LINK;
			break;
	}
	
	if(pName)
	{
		size = sprintf(gLoraSetBuffer, "%s+%s\r\n", pAT, pName);
	}
	else
	{
		size = sprintf(gLoraSetBuffer, "%s+\r\n", pAT);
	}
	
	if(size)
	{
		bspUsart3Send(gLoraSetBuffer, size);
		memset(gLoraSetBuffer,0,size);
		size = 0;
	}
}

void LoRaGetCmd(LoRaGetATCmd type)
{
	u32 size = 0;
	const	char* pAT = sBase_AT;
	const	char* pName = NULL;

	switch(type)
	{
		case LORA_GET_VERS:
			pName = sBase_VERS;
			break;
		case LORA_GET_BAUD:
			pName = sBase_BAUD;
			break;
		case LORA_GET_CONFIRM:
			pName = sBase_CONFIRM;
			break;
		case LORA_GET_NBTRIALS:
			pName = sBase_NBTRIALS;
			break;
		case LORA_GET_ADR:
			pName = sBase_ADR;
			break;
		case LORA_GET_CLASS:
			pName = sBase_CLASS;
			break;
		case LORA_GET_PORT:
			pName = sBase_PORT;
			break;
		case LORA_GET_SIGNAL:
			pName = sBase_SIGNAL;
			break;
		case LORA_GET_DATARATE:
			pName = sBase_DATARATE;
			break;
		case LORA_GET_JOIN:
			pName = sBase_JOIN;
			break;
		case LORA_GET_HEART:
			pName = sBase_HEART;
			break;
		case LORA_GET_CHANNEL:
			pName = sBase_CHANNEL;
			break;
		case LORA_GET_DEVEUI:
			pName = sBase_DEVEUI;
			break;
		case LORA_GET_APPEUI:
			pName = sBase_APPEUI;
			break;
		case LORA_GET_APPKEY:
			pName = sBase_APPKEY;
			break;
		case LORA_GET_POWER:
			pName = sBase_POWER;
			break;
		case LORA_GET_AUTO:
			pName = sBase_AUTO;
			break;		
	}
	
	if(pName)
	{
		size = sprintf(gLoraSetBuffer, "%s+%s?\r\n", pAT, pName);
	}
	
	if(size)
	{
		bspUsart3Send(gLoraSetBuffer, size);
		memset(gLoraSetBuffer,0,size);
		size = 0;
	}
}

void LoRaSetCmd(LoRaSetATCmd type, char* pArgs)
{
	u32 size;
	char* pAT ;
	char* pName ;

		pAT=sBase_AT;
		pName = NULL;
	switch(type)
	{
		case LORA_SET_BAUD:
			pName = sBase_BAUD;
			break;
		case LORA_SET_CONFIRM:
			pName = sBase_CONFIRM;
			break;
		case LORA_SET_NBTRIALS:
			pName = sBase_NBTRIALS;
			break;
		case LORA_SET_ADR:
			pName = sBase_ADR;
			break;
		case LORA_SET_CLASS:
			pName = sBase_CLASS;
			break;
		case LORA_SET_PORT:
			pName = sBase_PORT;
			break;
		case LORA_SET_DATARATE:
			pName = sBase_DATARATE;
			break;
		case LORA_SET_SEND:
			pName = sBase_SEND;
			break;
		case LORA_SET_SENDCK:
			pName = sBase_SENDCK;
			break;
		case LORA_SET_JOIN:
			pName = sBase_JOIN;
			break;
		case LORA_SET_SLEEP:
			pName = sBase_SLEEP;
			break;
		case LORA_SET_HEART:
			pName = sBase_HEART;
			break;
		case LORA_SET_CHANNEL:
			pName = sBase_CHANNEL;
			break;
		case LORA_SET_APPEUI:
			pName = sBase_APPEUI;
			break;
		case LORA_SET_APPKEY:
			pName = sBase_APPKEY;
			break;
		case LORA_SET_POWER:
			pName = sBase_POWER;
			break;
		case LORA_SET_AUTO:
			pName = sBase_AUTO;
			break;		
	}	
	
	if(pName)
	{
		size = sprintf(gLoraSetBuffer, "%s+%s=%s\r\n", pAT, pName, pArgs);
	}
	
	if(size)
	{
		bspUsart3Send(gLoraSetBuffer, size);
		memset(gLoraSetBuffer,0,size);
		size = 0;
	}
}


void LoRaJoinNet()
{
	bspUsart3Send("AT+JOIN=1\r\n",11);
		
}


/*
*********************************************************************************************************
*	�� �� ��: asciitohex
*	����˵��: �����ֽڵ�ascii��ϳ�1��16��������
*	�� �� ֵ: 16��������
*   ��    �ߣ�����
*   ��    �ڣ�2019-02-22
*********************************************************************************************************/
char asciitohex(char high_ascii,char low_ascii)
{
	char temp_high;
	char temp_low;
	if(high_ascii<=0x39)
		temp_high = high_ascii - 0x30;
		else
			temp_high = high_ascii - 0x57;
		
	if(low_ascii<=0x39)
		temp_low = low_ascii - 0x30;
		else
			temp_low = low_ascii - 0x57;
	
	
	temp_high = temp_high<<4 | 	temp_low;	
	
	return temp_high;
}

/*
*********************************************************************************************************
*	�� �� ��: lowhextoascii
*	����˵��: 16���Ƶĵ��ֽڵ�4bitת����ASCII��
*	�� �� ֵ: ASCII��
*   ��    �ߣ�����
*   ��    �ڣ�2019-02-22
*********************************************************************************************************/
char lowhextoascii(char hexdata)
{
	char temp;
	temp=hexdata&0x0f;
	if(temp<10)
		temp=temp+0x30;
	else
		temp=temp+0x37;
	return temp;
}

/*
*********************************************************************************************************
*	�� �� ��: Lora_Tx_Data
*	����˵��: ��232/485�յ���16�������ݣ�ת����ASCII�룬��lora����ȥ��������̫������ض�
*	�� �� ֵ: ��
*   ��    �ߣ�����
*   ��    �ڣ�2019-02-22
*********************************************************************************************************/
void Lora_Tx_Data(char* str, u32 length)
{
	u32 i;
	u32 Valid_Data_Len;
	
	
	
	
	Lora_TxData[0]='A';
	Lora_TxData[1]='T';
	Lora_TxData[2]='+';
	Lora_TxData[3]='S';
	Lora_TxData[4]='E';
	Lora_TxData[5]='N';
	Lora_TxData[6]='D';
	Lora_TxData[7]='=';
	Lora_TxData[8]='1';
	Lora_TxData[9]=',';
	Lora_TxData[10]='4';
	Lora_TxData[11]=',';
	if(length<=Valid_Data_Len_Max)
		Valid_Data_Len = length;
	else
		Valid_Data_Len = Valid_Data_Len_Max;
	/*
	Lora_TxData[12]='5';
	Lora_TxData[13]='A';
	Lora_TxData[14]='5';
	Lora_TxData[15]='A';
	Lora_TxData[16]='5';
	Lora_TxData[17]='A';
	Lora_TxData[18]='5';
	Lora_TxData[19]='A';
	*/
	for(i=0;i<Valid_Data_Len;i++)
	{
		Lora_TxData[2*i+13] = lowhextoascii(str[i]);
		Lora_TxData[2*i+12] = lowhextoascii(str[i]>>4);
	}
	Lora_TxData[2*i+12] = '\r';
	Lora_TxData[2*i+13] = '\n';
	bspUsart3Send(Lora_TxData, (2*i+14));
	
}


/*
*********************************************************************************************************
*	�� �� ��: Check_Lora_Join_Status
*	����˵��: ���lora�Ƿ�����(�ڷ�������֮ǰ)����������1������������0
*	�� �� ֵ: �Ƿ�����
*   ��    �ߣ�����
*   ��    �ڣ�2019-02-22
*********************************************************************************************************/
u8 Check_Lora_Join_Status()
{
	bspUsart3CleanData();
	bspUsart3Send("AT+JOIN?\r\n",10);
	delay(200);
	if(gLoRaRxFlag)
	{
		gLoRaRxFlag = 0;						
		gLoraRxSize = bspUsart3Receive((void*)&gptrLoraRx);
		if(strstr(gptrLoraRx, "OK+JOIN:02\r\n") != NULL)
			return 1;
		else
			return 0;
	}
	else
		return 0;
}

/*
*********************************************************************************************************
*	�� �� ��: Set_Lora_Join
*	����˵��: lora����
*	�� �� ֵ: �Ƿ�ɹ��������ɹ�����ֵ1��ʧ�ܷ���ֵ0
*   ��    �ߣ�����
*   ��    �ڣ�2019-02-22
*********************************************************************************************************/
u8 Set_Lora_Join()
{
	u16 i;
	bspUsart3Send("AT+JOIN=1\r\n",11);
	delay(500);
	bspUsart3CleanData();
	i=200;
	while(i--)
	{
		bspUsart3Send("AT+JOIN?\r\n",10);
		delay(500);
		if(gLoRaRxFlag)
		{
			gLoRaRxFlag = 0;						
			gLoraRxSize = bspUsart3Receive((void*)&gptrLoraRx);
			if(strstr(gptrLoraRx, "OK+JOIN:02\r\n") != NULL)
				{
					bspUsart3CleanData();
					return 1;
								
			    }

			else if(strstr(gptrLoraRx, "ERR+JOINED:0005,0005\r\n") != NULL)
				{
					bspUsart3CleanData();
					return 0;
				}
			else
			{
				bspUsart3CleanData();
			}					
		}
	}

}










